#ifndef WEIGHT_MAP_HPP
#define WEIGHT_MAP_HPP

#include <algorithm>
#include <stdexcept>
#include <sstream>
#include "bitmap.hpp"

class weightmap
{
public:
 typedef short field_t;
 /*static const char max_value = std::numeric_limits<char>::max();
 static const char min_value = std::numeric_limits<char>::min();
 */

  weightmap()
    : rows(0)
    , cols(0)
    , _size(0)
    , _weightmap(0)
  {
  }

  ~weightmap()
  {
    delete[] _weightmap;
  }

  
  void reset()
  {
    if ( _weightmap )
      std::fill(_weightmap, _weightmap + _size, 0);
  }

  void create(int r, int c)
  {
    rows = r;
    cols = c;
    _size = rows * cols;
    _weightmap = new field_t[_size];
    this->reset();
  }

  field_t get( location loc ) const
  {
    return _weightmap[ loc.row * cols + loc.col];
  }
  
  void set( location loc, field_t val )
  {
    _weightmap[ loc.row * cols + loc.col] = val;
  }
  
  // val = +- 1 only
  void inc( location loc, short val, double radius, bool centr)
  {
    int fr = loc.row - radius;
    int tr = loc.row + radius;
    int fc = loc.col - radius;
    int tc = loc.col + radius;

    for ( int i = fr; i <= tr; ++i)
    {
      for ( int j = fc; j <= tc; ++j)
      {
        int r = i;
        if (r < 0) r += rows;
        if (r >= rows ) r -= rows;
        int c = j;
        if (c < 0) c += cols;
        if (c >= cols ) c -= cols;

        location cur(r, c);
        if ( location::distance( loc, cur, location(rows, cols) ) <= radius )
        {
          field_t cval = get( cur );
          int res = 0;
          if ( centr && ( r == loc.row && c == loc.col) )
            res = cval - val * 1024 /*radius*/;
          else
            res = cval + val ;
          set( cur, res );
        }
      }
    }
  }
  
    void show(std::ostream& os, std::string text = "")
  {
    os << "--- weight "<< text<< "------------------ " << std::endl;
    for ( int i = 0; i < rows; ++i)
    {
      for ( int j = 0; j < cols; ++j)
      {
        location loc(i, j);
        int val = this->get( loc );
        if (val>0)
          os << "+";
        else if (val<0)
          os << "-";
        else
          os << "0";
        
      }
      os << std::endl;
    }
    os << std::endl;
  }


private:


  int rows, cols;
  size_t _size;
  field_t* _weightmap;
};

#endif

